
jQuery.fn.extend({

    crudForm: function(options) {
        if (typeof(options) === 'object') {

        }
    },

    dxInit: function() {
        $("[dx-toggle]", $(this)).each(function () {
            if ($(this).hasClass("dx-widget")) {
                return true;
            }

            var type = $(this).attr("dx-toggle"), options = $(this).attr("dx-options") || "{}";

            try {
                options = JSON.parse(options);
            } catch(ex) {

                options = {};
            }


            switch(type) {
                case "button":
                    $(this).dxButton(options);
                    break;

                case "select":
                    $(this).dxSelectBox(options);
                    break;

                case "text":
                    $(this).dxTextBox(options);
                    break;

                case "textarea":
                    $(this).dxTextArea(options);
                    break;

                case "number":
                    $(this).dxNumberBox(options);
                    break;

                case "check":
                    $(this).dxCheckBox($.extend({text: $(this).text()}, options));
                    break;

                default:
                    console.log("Error: unsupported type " + type);
                    break;
            }
        });

        return $(this);
    },
    dxDelete :function (url,option){
        $("<a>").text("删除").click(function(){
                var id=option.key.id;
            DevExpress.ui.dialog.confirm("确定删除吗?", "请确认").done(function(sele){

                if(sele){

            $.ajax({type:"delete",
                    url:$.config('apiUrl')+"restful/"+id+"?_model="+url
                 }).then(function(a){

                if(a.status="success"){

                    DevExpress.ui.notify({
                      message: function() {

                       gridComponent = $("#content .crud-grid").dxDataGrid('instance');

                     gridComponent.option('dataSource').load();

                       return "成功删除";
                                     }
                                   },"success", 1000)

                               }else{

                    DevExpress.ui.notify({

                      message: function() {

                       return "操作失败";
                                     }
                                   },"warning", 1000)
                         }
                      })
                    }
                })
        }).appendTo(this);
        return this
    },
    dxUpdown:function(url,option){
        var text=option.value=='yes'?'下线':'上线',
            off=option.value=='yes'?'no':'yes';

         $('<a>').text(text).css({'text-decoration':'underline'}).click(function(){
            $.post(
                $.config('apiUrl')+"state-change",
                {
                   'changeType':url,
                    'changeKey':'online',
                    'changeValue':off,
                    'changeId':option.key.id
                },
                function(d){
        if(d.status){
            DevExpress.ui.notify({
                message: function() {
                     gridComponent = $("#content .crud-grid").dxDataGrid('instance');
                     gridComponent.option('dataSource').load();
                    return off=='yes'?'上线成功':'下线成功';
                                     }
                        },"success", 1000)
                    }else{
            DevExpress.ui.notify({
                message: function() {
                    return '操作失败';
                                     }
                        },"warning", 1000)
                    }
             })
        }).appendTo(this)
         return this
    },
    dxWeight:function(url,option){

         $('<a>').text(option.value==null?'无':option.value).css({'text-decoration':'underline'}).click(function(){
            var number=prompt('请输入权重',option.value);
            if(number==null){return };
            if(number>=0&&number<=100){
                 $.post(
                $.config('apiUrl')+"state-change",
                {
                   'changeType':url,
                    'changeKey':'weight',
                    'changeValue':number,
                    'changeId':option.key.id
                },
                function(d){
                    if(d.status){
            DevExpress.ui.notify({
                message: function() {
                     gridComponent = $("#content .crud-grid").dxDataGrid('instance');
                     gridComponent.option('dataSource').load();
                    return '修改成功';
                                     }
                        },"success", 1000)
                    }else{
            DevExpress.ui.notify({
                message: function() {
                    return '操作失败';
                                     }
                        },"warning", 1000)
                    }
                })
            }else{
                DevExpress.ui.notify({
                    message:'请输入正确的值'},
                    'warning',
                    1000  )

            }
         }).appendTo(this);
         return this
    }
});

var DxExtInstance = klass(function ($container, config, opt) {
    this.$container = $container;
    this.opt = $.extend({}, opt);
    this.config = $.extend({}, config);
    this.user = {};
    this.config.init.call(this, this.$container, opt);

    this.setValue(opt.value || undefined);
}).statics({
    validate: function(formInstance) {
        var editors = [];

        function _check(o) {
            if (o.dataField) {
                var editor = formInstance.getEditor(o.dataField);
                if (editor && typeof(editor.isExtInstance) === 'function') {
                    editors.push(editor);
                }
            } else if (o.items) {
                $.each(o.items, function(i, item) {
                    _check(item);
                })
            }
        }

        _check({items: formInstance.option('items')});

        var result = true;
        $.each(editors, function(i, e) {
            if (! e.validate()) result = false;
        });

        return result;
    },

    define: function(config) {
        var obj = {};
        obj[config.name] = function() {
            var instance = $(this).data('dx-ext-instance');

            if (arguments.length > 0 && typeof(arguments[0]) === 'object') {

                if (! instance) {
                    instance = new DxExtInstance($(this), config, arguments[0]);
                    $(this).data('dx-ext-instance', instance);
                }

                return $(this);
            } else if (arguments.length > 0 && typeof(arguments[0]) === 'string') {
                var args = [];
                for (var i = 1; i < arguments.length; i++) {
                    args.push(arguments[i]);
                }

               
                return instance[arguments[0]].apply(instance, args);
            } else {
                return undefined;
            }
        };

        jQuery.fn.extend(obj);
    }
}).methods({
    isExtInstance: function() {
        return true;
    },

    validate: function() {
        if (this.config.validate) {
            return this.config.validate.call(this);
        } else {
            return true;
        }
    },

    getValue: function() {
        if (this.config.onGetValue) return this.config.onGetValue.call(this);
        return this.value;
    },

    getOption: function() {
        return this.opt;
    },

    notifyValueChanged: function() {
        this.$container.trigger("dxExtValueChanged");
    },

    setValue: function(v, preventRender) {
        this.value = v;
        this.notifyValueChanged();
        if (! preventRender) this.render();
    },

    render: function() {
        this.config.render && this.config.render.call(this, this.$container);
    },

    setAria: function() {
        return undefined;
    },

    option: function(k, v) {

        if (k === 'value' && v !== undefined) {
            return this.setValue(v);
        } else if (k === 'value') {
            if (this.config.beforeGetValue) {
                this.config.beforeGetValue.call(this);
            }
            return this.getValue();
        }

        if (v === undefined) {

            return this.opt[k]
        } else {
            var orig = this.opt[k];
            this.opt[k] = v;

            if (this.config.onOptionChanged) {
                this.config.onOptionChanged.call(this, {option: k, value: v, oldValue: orig});
            }
        }
    },

    element: function() {
        return this.$container;
    },

    instance: function() {
        return this;
    },

    on: function(evt, fn) {
        var _this = this;


        if (evt === 'valueChanged') {
            this.$container.on("dxExtValueChanged", function() {
                fn.call(_this, {component: _this, value: _this.value});
            })
        }

    },

    reset: function() {
        console.log("call reset");
    }
});

DxExtInstance.define({
    name: 'ImageUploader',
    init: function($container, option) {
        var _this = this;

        option = $.extend({}, {single: false}, option);

        $container.html("<div class='images'></div><div class='file image-uploader'></div>");

        var labelText = '';
        if (option.labelText) {
            labelText = option.labelText;
        } else if (option.imageWidth && option.imageHeight) {
            labelText = '建议宽高比是' + option.imageWidth + 'px x ' + option.imageHeight + 'px。';
        }

        $container.find(".file").dxFileUploader({
            selectButtonText: "上传",
            labelText : labelText,
            name : 'file',
            accept : "image/*",
            uploadMode : "instantly",
            uploadUrl : $.config('apiUrl')+"file-upload",
            onUploaded : function(e){
                var pat = JSON.parse(e.request.response).data;

                var value = _this.getValue();

                if (value === undefined){
                    value = (option.single ? "" : []);
                };

                if (option.single) {
                    value = pat.imgSrv;
                } else {
                    value.push(pat);
                }

                _this.setValue(value);
            }
        });

        // $container.find(".file .dx-button-content").html('<i class="iconfont">&#xe623;</i>');
    },

    render: function($container) {
        function imageUrl(url) {
            if (! url.match(/imageView2/)) {
                url += "?imageView2/1/w/100/h/57";
            }

            return url;
        }

        var _this = this, value = this.getValue();

        var $images = $container.find(".images");
        $images.html("");

        if (value) {
            var option = this.getOption();

            if (option.single) value = [value];

            $.each(value, function(i, dat){
                $("<div>").append($("<img>").attr("src", imageUrl(option.single ? dat : dat.imgSrv))).append($("<span>").text("删除").click(function(){

                    if (! option.single) {
                        value.splice(i, 1);
                        _this.setValue(value);
                    } else {
                        value = "";
                        _this.setValue(value);
                    }

                    $(this).parent().remove();
                })).appendTo($images);
            });
        }
    }
});

DxExtInstance.define({
    name: 'VideoUploader',
    init: function($container, option) {
        var _this = this;

        option = $.extend({}, {single: false}, option);

        $container.html("<div class='video-url'></div><div class='file'></div>");

        $container.find(".file").dxFileUploader({
            selectButtonText: "上传",
            labelText : '',
            name : 'file',
            accept : "video/mp4,video/x-m4v,video/*",
            uploadMode : "instantly",
            uploadUrl : $.config('apiUrl')+"file-upload",
            onUploaded : function(e) {
                var pat = JSON.parse(e.request.response).data;

                _this.setValue(pat.imgSrv);
            }
        });

        $container.find(".video-url").dxTextBox({
            onValueChanged: function(e) {
                _this.setValue(e.value);
            },
            placeholder: '视频地址'
        });
    },
    render: function($container) {
        var v = $container.find(".video-url").dxTextBox("option", "value");
        if (v != this.getValue()) {
            $container.find(".video-url").dxTextBox("option", "value", this.getValue());
        }
    }
});

DxExtInstance.define({
    name:'setDateDay',
    init: function($container, option) {
        let _this = this;
        let template = '<div style="width:260px;height:36px;line-height:36px" class="setDateMonth">'+
                        '<div class="button_left pull-left text-center" style="width:36px;height:36px;cursor:pointer;"><i class="fa fa-fw fa-angle-left text"></i></div>'+
                        '<div class="input_text pull-left" style="background:#fff;height:36px;width:175px;border:1px solid #eee;border-width:0 1px;text-align:center;line-height:36px"></div>'+
                        '<div class="button_right pull-left text-center" style="width:36px;height:36px;cursor:pointer"><i class="fa fa-fw fa-angle-right text"></i></div>'+
                        '</div>'

        $container.html(template)
        let setDate = function(date){
             _this.setValue(moment(date).format('YYYY-MM-DD'));
             _this.getOption().onValueChanged(moment(date).format('YYYY-MM-DD'))
        };
        $container.find('.button_left').click(function(){
            setDate(moment(_this.getValue()).subtract(1,'d'))
        })
        $container.find('.button_right').click(function(){
            setDate(moment(_this.getValue()).add(1,'d'))
        })
       

    },
    render:function($container){
      let value = this.getValue(),_this = this;
      $container.find('.input_text').dxDateBox({
            placeholder:'请选择时间',
            type:'date',
            value:value,
            displayFormat: 'yyyy-MM-dd',
            dateSerializationFormat: "yyyy-MM-dd",
            onValueChanged:function(e){
                _this.setValue(e.value)
                _this.getOption().onValueChanged(moment(e.value).format('YYYY-MM-DD'))
            }
        })
    }
})


DxExtInstance.define({
    name:'setDateMonth',
    init: function($container, option) {
        let _this = this,date = new Date();
        let template = '<div style="width:200px;height:36px;line-height:36px" class="setDateMonth">'+
                        '<div class="button_left pull-left text-center" style="width:36px;height:36px;cursor:pointer;"><i class="fa fa-fw fa-angle-left text"></i></div>'+
                        '<div class="input_text pull-left" style="background:#fff;height:36px;width:116px;border:1px solid #eee;border-width:0 1px;text-align:center;line-height:36px"></div>'+
                        '<div class="button_right pull-left text-center" style="width:36px;height:36px;cursor:pointer"><i class="fa fa-fw fa-angle-right text"></i></div>'+
                        '</div>'

        $container.html(template)
        let setDate = function(){
             _this.setValue(moment(date).format('YYYY-MM'));
             _this.getOption().onValueChanged(moment(date).format('YYYY-MM'))
        };
        $container.find('.button_left').click(function(){
            date = moment(date).subtract(1,'M')
            setDate()
        })
        $container.find('.button_right').click(function(){
            date = moment(date).add(1,'M')
            setDate()
        })
       

    },
    render:function($container){
      let value = this.getValue();;
      $container.find('.input_text').text(value)
    }
})

DxExtInstance.define({
    name: 'GrapeList',
    init: function($container, option) {
       
    },
    render: function($container) {
        var v = this.getValue(), _this = this;

        v = v || [];

        var tpl = '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<div class="pull-left" style="line-height: 36px; margin-right: 10px;">葡萄</div>' +
            '<div class="pull-left"><div class="grape-input-name"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin: 0 10px;">种植面积占比</div>' +
            '<div class="pull-left"><div class="grape-input-area"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin-left: 20px;"><div class="grape-remove"></div>' +
            '</div></div>';

        $container.html('');
        $.each(v, function(i, item) {
            var $c = $(tpl);

            $c.find(".grape-input-name").dxTextBox({
                width: 200,
                value: item.name,
                onValueChanged: function(e) {
                    v[i].name = e.value;
                }
            });

            $c.find(".grape-input-area").dxNumberBox({
                width: 80,
                value: item.proportion,
                showSpinButtons: true,
                // format: "#0%",
                onValueChanged: function(e) {
                    v[i].proportion = e.value;
                }
            });

            $c.find(".grape-remove").dxButton({
                text: '删除',
                onClick: function() {
                    v.splice(i, 1);
                    _this.setValue(v);
                }
            });

            $c.appendTo($container);
        });

        $("<div/>").dxButton({
            text: '增加',
            onClick: function() {
                v.push({name: '', area: 0});
                _this.setValue(v);
            }
        }).appendTo($container);
    }
});

DxExtInstance.define({
    name: 'GrapeDeployList',

    validate: function() {
        try {
            var result = DevExpress.validationEngine.validateGroup(this.validationGroup);
            if (result.isValid) {
                var value = this.getValue(), err = false;
                value = value || [];

                this.opt.isValid = false;
                this.opt.validationError = "";

                if (this.opt.mode === 'single') {
                    
                } else if (this.opt.mode === 'blend') {
                    var total = 0;
                    $.each(value, function(i, v) {
                        total += parseFloat(v.scale);
                    });

                    if (value.length < 2) {
                        err = '至少配置两种葡萄';
                    } else if (total > 100) {
                        err = '比例设置超过100';
                    }
                } else {
                }

                if (! err) {
                    this.opt.isValid = true;
                } else {
                    this.opt.validationError = err;
                    
                }
            }

            this.setValue(value);
        } catch(e) {
            this.opt.isValid = false;
        }
        

        return this.opt.isValid;     
    },

    init: function($container, option) {
        this.opt.mode = this.opt.mode || 'single';
        this.validationGroup = 'GrapeDeployList-' + Math.floor(Math.random() * 1000);


        // this.setValue(null);
    },

    render: function($container) {
        var v = this.getValue(), _this = this;

        v = v || [];

        var validationGroup = this.validationGroup;
        var vtpl = '<div class="dx-ex-validation-error"></div>';
        var tpl = '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<div class="pull-left" style="line-height: 36px; margin-right: 10px;">葡萄</div>' +
            '<div class="pull-left"><div class="grape-input-name"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin: 0 10px;">比例</div>' +
            '<div class="pull-left"><div class="grape-input-area"></div></div>' +
            (this.opt.mode === 'blend' ? 
            '<div class="pull-left" style="line-height: 36px; margin-left: 20px;"><div class="grape-remove"></div></div>'
            : '') + 
            '</div></div>';

        $container.html('');

        if (! this.opt.isValid && this.opt.validationError) {
            $('<div class="dx-ex-validation-error">' + this.opt.validationError + '</div>').appendTo($container);
        }

        $.each(v, function(i, item) {
            var $c = $(tpl);

            $c.find(".grape-input-name").dxTextBox({
                width: 200,
                value: item.name,
                onValueChanged: function(e) {
                    v[i].name = e.value;
                }
            }).dxValidator({
                validationGroup: validationGroup,
                validationRules: [{
                    type: 'required'
                }]
            });

            $c.find(".grape-input-area").dxNumberBox({
                width: 80,
                value: item.scale,
                showSpinButtons: true,
                // format: "#0%",
                onValueChanged: function(e) {
                    v[i].scale = e.value;
                }
            }).dxValidator({
                validationGroup: validationGroup,
                validationRules: [{
                    type: 'required'
                }]
            });;

            $c.find(".grape-remove").dxButton({
                text: '删除',
                onClick: function() {
                    v.splice(i, 1);
                    _this.setValue(v);
                }
            });

            $c.appendTo($container);
        });

        if (this.opt.mode === 'blend') {
            $("<div/>").dxButton({
                text: '增加',
                onClick: function() {
                    v.push({name: '', scale: 100});
                    _this.setValue(v);
                }
            }).appendTo($container);
        }

        if (v.length == 0) {
            $container.html('未选择调配类型');
        }
    },

    onOptionChanged: function(e) {
        if (e.option === 'mode') {
            var value = this.getValue();

            this.opt.isValid = true;
            this.opt.validationError = "";
            
            if (value) {
                if (e.value === 'single') {
                    if (value.length >= 1) {
                        value = value.slice(0, 1);
                    } else {
                        value.push({name: '', scale: 100});
                    }
                } else if (e.value === 'blend') {
                    value = value.slice(0, 20);

                    while(value.length < 2) {
                        value.push({name: '', scale: 0});
                    }
                }

                this.setValue(value);
            } else {
                if (e.value === 'single') {
                    value = [{name: '', scale: 100}];
                } else if (e.value === 'blend') {
                    value = [];

                    while(value.length < 2) {
                        value.push({name: '', scale: 0});
                    }
                }

                this.value = value;
                this.render();
            }

        } else if (e.option === 'isValid') {

        } else if (e.option === 'validationError') {

        }
    }
});

DxExtInstance.define({
    name: 'dxEditor',
    init: function($container, option) {

        var _this = this;
        option = $.extend({}, {single: false}, option);

        $container.append(  "<textarea>" );

        // editorH1 editorH3

        // CKEDITOR.basePath = '../libs/ckeditor/';
        this.editor = CKEDITOR.replace($container.find('textarea')[0], {
            height: 300,
            allowedContent: true,

            // Upload images to a CKFinder connector (note that the response type is set to JSON).
            uploadUrl: $.config('apiUrl') + "file-upload",

            // Load the default contents.css file plus customizations for this sample.
            contentsCss: [ CKEDITOR.basePath + 'contents.css' ],
        });

        this.editor.on("change", function(evt) {
            _this.setValue(_this.editor.getData());
        });

        this.editor.on("notificationHide", function(evt) {
            _this.setValue(_this.editor.getData());
        });
    },

    render: function($container) {
        if (this.editor) {
            var html = this.editor.getData();
            if (! html && this.getValue()) {
                var _this = this;
                // 直接调用偶尔会失败，原因未知
                setTimeout(function () {
                    _this.editor.setData(_this.getValue());
                }, 0);
            }
        }
    },

    beforeGetValue: function() {
        if (this.editor) {
            this.value = this.editor.getData();
            this.notifyValueChanged();
        }
    }
});


DxExtInstance.define({
    name: 'Tfselect',
    init: function($container, option) {
        var _this = this,itemData=[];
         option = $.extend({}, {single: false}, option);

         if (option.value) {
            $.each(option.value,function(i,va){
                $('<div>').append( $('<div class="tfselect">').dxSelectBox({
                    dataSource:va,
                    disabled:true,
                    displayExpr: "expert_judges",
                    valueExpr: "id",
                    deferRendering: false
                }) ).append( $('<div class="tftextarea">').dxTextArea({
                    value:va.content
                })  ).append( $('<div class="tfdelete">').dxButton({
                    text:'删除',
                    type:'normal'
                })).appendTo($container)



             })
         }
         

        $container.append( $('<div class="tfbutton">').dxButton({
            text:'增加专家鉴',
            type:'normal',
            onClick:function(){
             $container.find('.tfbutton').before(

            $('<div>').append( $('<div>').dxSelectBox({
                dataSource:new DevExpress.data.DataSource({
                    store: $.crudStore(API("restful?_model=expert-user") )
                }),
                displayExpr:'name',
                valueExpr:'id',


            }) ).append( $('<div>').dxTextArea({

            })  ).append( $('<div>').dxButton({
                text:'删除',
                type:'normal'

                             }))
                        );
                    }
                })  )

         },
    render: function($container) {

    }
});


DxExtInstance.define({
    name: 'Tfexpret',
    init: function($container, option) {
        var _this = this;
         option = $.extend({}, {single: false}, option);

         $container.append( $("<div>").dxSelectBox({
                dataSource:option.value,
                value:option.value[0].id,
                displayExpr:'expert_user_name',
                valueExpr:'id',
                 showClearButton: true,
                placeholder: "分类",
                searchEnabled: true,
                noDataText: '没有请求到分类数据',
                deferRendering: false,
                onValueChanged:function(e){
                   _this.setValue(e.value)
                }
         })  )

         },
    render: function($container) {

    }
});


DxExtInstance.define({
    name: 'Tfscore',
    init: function($container, option) {
        var _this = this;
         option = $.extend({}, {single: false}, option);
         var docu=$("<div> <span>专家评分</span> <div class='tfselect' ></div> <span>评分</span> <div class='tftext'></div>   </div>" )



        docu.find("span").css({"margin":"10px","width":"10%"})

        var boxtext = docu.find(".tftext").dxTextBox({

        }).data("dxTextBox");


        docu.find(".tfselect").dxSelectBox({
            dataSource:option.value,
            displayExpr:"expert_user_name",
            valueExpr:'score',
            showClearButton:true,
            noDataText:'没有专家评分',
            placeholder:'专家分类',
            onValueChanged:function(e){
                boxtext.option("value",e.value)
            }
        });

        docu.appendTo($container)

         },
    render: function($container) {

    }
});


DxExtInstance.define({
    name: 'Tfsame_score',
    init: function($container, option) {
        var _this = this;
         option = $.extend({}, {single: false}, option);
         var docu=$("<div> <span>生产年份</span> <div class='tfselect' ></div> <span>平均分</span> <div class='tftext'></div>   </div>" )



        docu.find("span").css({"margin":"10px","width":"10%"})

        var boxtext = docu.find(".tftext")

        var boxselect = $("<div>").dxSelectBox({
            dataSource:[],
            displayExpr:'expert_user_name',
            valueExpr:'expert_user_id',
            showClearButton:true,
            noDataText:'没有数据',
            onSelectionChanged:function(e){

            }
        });

        docu.find(".tfselect").dxSelectBox({
            dataSource:option.value,
            displayExpr:"vintage",
            valueExpr:'averageScore',
            showClearButton:true,
            noDataText:'没有同系列酒',
            placeholder:'同系列酒分类',
            value:'expert_scores',
            onSelectionChanged:function(e){ 
                boxtext.text( e.selectedItem.averageScore );
                boxselect.option('dataSource',e.selectedItem.expert_scores)
            }
        });

        docu.appendTo($container)
        boxselect.appendTo($container)
         },
    render: function($container) {

    }
});

DxExtInstance.define({
    name: 'ExpertList',
    init: function($container, option) {
    },
    render: function($container) {
        var v = this.getValue(), _this = this;

        v = v || [];

        var tpl = '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<div class="pull-left" style="width: 120px; line-height: 36px;">专家</div>' +
            '<div class="pull-left" style="width: 50%;"><div class="expert-input-name"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin-left: 20px;"><div class="expert-remove"></div></div>' +
            '</div></div>' +
            '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<div class="pull-left" style="width: 120px; line-height: 36px;">点评内容</div>' +
            '<div class="pull-left" style="width: 50%;"><div class="expert-input-area"></div></div>' +
            '</div></div>';

        $container.html('');
        $.each(v, function(i, item) {
            var $c = $(tpl);

            $c.find(".expert-input-name").dxSelectBox({
                dataSource: $.crudStore(API('restful?_model=expert-user')),
                showClearButton: true,
                placeholder: "专家",
                searchEnabled: true,
                valueExpr: 'id',
                noDataText: '没有请求到专家数据',
                itemTemplate: function(data, index, $el) {
                  if (data) {
                    $("<span>" + data.name + " (" + data.account + ")</span>").appendTo($el);
                  }
                },
                displayExpr: function(data) {
                  return data ? data.name + " (" + data.account + ")" : "";
                },
                width: '100%',
                value: item.expert_user_id,
                onValueChanged: function(e) {
                    v[i].expert_user_id = e.value;
                }
            });

            $c.find(".expert-input-area").dxTextArea({
                width: '100%',
                value: item.content,
                onValueChanged: function(e) {
                    v[i].content = e.value;
                }
            });

            $c.find(".expert-remove").dxButton({
                text: '删除',
                onClick: function() {
                    v.splice(i, 1);
                    _this.setValue(v);
                }
            });

            $c.appendTo($container);
        });

        $("<div/>").dxButton({
            text: '增加',
            onClick: function() {
                v.push({expert_user_id: 0, content: ''});
                _this.setValue(v);
            }
        }).appendTo($container);
    }
});

DxExtInstance.define({
    name: 'ExpertScoreList',
    init: function($container, option) {
        $container.html(
            '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<h3 class="pull-left score-year-title">本款酒</h3>' +
            '<div class="score-title pull-left" style="line-height: 36px; margin: 0 10px;">平均分 <span class="avg-score">0</span></div>' +
            '</div></div>' +
            '<div class="score-container"></div>');
    },
    render: function($container) {
        var v = this.getValue(), _this = this, $content = $container.find(".score-container");

        v = v || [];

        var tpl = '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<div class="pull-left" style="line-height: 36px; margin-right: 10px;">专家</div>' +
            '<div class="pull-left"><div class="expert-input-name"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin: 0 10px;">评分</div>' +
            '<div class="pull-left"><div class="expert-input-area"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin-left: 20px;"><div class="expert-remove"></div>' +
            '</div></div>';

        var updateScore = function() {
            var v = _this.getValue() || [], s = 0;

            $.each(v, function(i, vitem) {
                var n = parseInt(vitem.score) || 0;
                s += n;
            });

            $(".avg-score", $container).text(v.length > 0 ? Math.ceil(s / v.length) : 0);
        }

        $content.html('');
        $.each(v, function(i, item) {
            var $c = $(tpl);

            $c.find(".expert-input-name").dxSelectBox({
                dataSource: $.crudStore(API('restful?_model=expert-user')),
                showClearButton: true,
                placeholder: "专家",
                searchEnabled: true,
                valueExpr: 'id',
                noDataText: '没有请求到专家数据',
                itemTemplate: function(data, index, $el) {
                  if (data) {
                    $("<span>" + data.name + " (" + data.account + ")</span>").appendTo($el);
                  }
                },
                displayExpr: function(data) {
                  return data ? data.name + " (" + data.account + ")" : "";
                },
                value: item.expert_user_id,
                onValueChanged: function(e) {
                    v[i].expert_user_id = e.value;
                }
            });

            $c.find(".expert-input-area").dxNumberBox({
                width: 80,
                value: item.score,
                showSpinButtons: true,
                // format: "#0%",
                onValueChanged: function(e) {
                    v[i].score = e.value;
                    updateScore();
                }
            });

            $c.find(".expert-remove").dxButton({
                text: '删除',
                onClick: function() {
                    v.splice(i, 1);
                    _this.setValue(v);
                }
            });

            $c.appendTo($content);
        });

        $("<div/>").dxButton({
            text: '添加专家评分',
            onClick: function() {
                v.push({expert_user_id: 0, score: 0});
                _this.setValue(v);
            }
        }).appendTo($content);

        updateScore();
    }
});

DxExtInstance.define({
    name: 'ExpertYearScoreList',
    init: function($container, option) {
    },
    render: function($container) {
        var v = this.getValue(), _this = this;

        v = v || [];

        var tplH = '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<h3 class="pull-left score-year-title">同系列酒</h3>' +
            '<div class="pull-right"><div class="score-year-remove"></div></div>' +
            '</div></div>';

        var tpl0 = '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<div class="pull-left" style="line-height: 36px; margin-right: 10px;">生产年份</div>' +
            '<div class="pull-left"><div class="score-year"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin: 0 10px;">平均分 <span class="avg-score">0</span></div>' +
            '</div></div>' +
            '<div class="score-container"></div>' +
            '<div style="margin-top: 20px;"><div class="expert-add"></div></div>';

        var tpl = '<div class="row" style="margin-bottom: 10px;"><div class="col-sm-12">' +
            '<div class="pull-left" style="line-height: 36px; margin-right: 10px;">评分专家</div>' +
            '<div class="pull-left"><div class="expert-input-name"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin: 0 10px;">评分</div>' +
            '<div class="pull-left"><div class="expert-input-area"></div></div>' +
            '<div class="pull-left" style="line-height: 36px; margin-left: 20px;"><div class="expert-remove"></div>' +
            '</div></div>';

        var years = [];
        for (var y = 1950; y <= 2020; y++) years.push(y);

        var updateScore = function() {
            var v = _this.getValue() || [], s = 0;

            $.each(v, function(i, vitem) {
                var n = parseInt(vitem.score) || 0;
                s += n;
            });

            $(".avg-score", $container).text(v.length > 0 ? Math.ceil(s / v.length) : 0);
        }

        $container.html('');
        $.each(v, function(i, item) {
            var $c0 = $("<div style='margin-bottom: 20px;'>" + tplH + tpl0 + "</div>");

            $c0.find(".score-year-title").text('同系列酒 #' + i);

            $c0.find(".score-year-remove").dxButton({
                text: '删除',
                onClick: function() {
                    v.splice(i, 1);
                    _this.setValue(v);
                }
            });

            $c0.find(".score-year").dxSelectBox({
                dataSource: years,
                acceptCustomValue: true,
                value: v[i].vintage,
                onValueChanged: function(e) {
                    v[i].vintage = e.value;
                }
            });

            var $cc = $c0.find(".score-container");

            if (v[i].expert_scores) {
                v[i].items = v[i].expert_scores;
                v[i].expert_scores = undefined;
            } else {
                v[i].items = v[i].items || [];
            }

            $c0.find(".expert-add").dxButton({
                text: '添加评分',
                onClick: function() {
                    v[i].items.push({expert_user_id: 0, score: 0});
                    _this.setValue(v);
                }
            });

            $.each(item.items, function(k, item) {
                var $c = $(tpl);

                $c.find(".expert-input-name").dxSelectBox({
                    dataSource: $.crudStore(API('restful?_model=expert-user')),
                    showClearButton: true,
                    placeholder: "专家",
                    searchEnabled: true,
                    valueExpr: 'id',
                    noDataText: '没有请求到专家数据',
                    itemTemplate: function(data, index, $el) {
                      if (data) {
                        $("<span>" + data.name + " (" + data.account + ")</span>").appendTo($el);
                      }
                    },
                    displayExpr: function(data) {
                      return data ? data.name + " (" + data.account + ")" : "";
                    },
                    value: item.expert_user_id,
                    onValueChanged: function(e) {
                        v[i].items[k].expert_user_id = e.value;
                    }
                });

                $c.find(".expert-input-area").dxNumberBox({
                    width: 80,
                    value: item.score,
                    showSpinButtons: true,
                    // format: "#0%",
                    onValueChanged: function(e) {
                        v[i].items[k].score = e.value;
                        updateScore();
                    }
                });

                $c.find(".expert-remove").dxButton({
                    text: '删除',
                    onClick: function() {
                        v[i].items.splice(k, 1);
                        _this.setValue(v);
                    }
                });

                $c.appendTo($cc);
            });

            $c0.appendTo($container);
        });

        $("<div/>").dxButton({
            text: '添加同系列酒',
            onClick: function() {
                v.push({vintage: "1900", items: []});
                _this.setValue(v);
            }
        }).appendTo($container);

        updateScore();
    }
});

DxExtInstance.define({
    name: 'YearSelect',
    init: function($container, option) {
        var years = [], _this = this;
        for (var y = 1950; y <= 2050; y++) years.push(y);

        $("<div class='year-select'/>").appendTo($container).dxSelectBox({
            dataSource: years,
            acceptCustomValue: true,
            onValueChanged: function(e) {
                _this.setValue(e.value);
            },
            displayExpr: function(v) {
                return v ? v + '年' : '';
            }
        });
    },
    render: function($container) {
        var v = this.getValue(), v0 = $(".year-select", $container).dxSelectBox("option", "value");

        if (v != v0) {
            $(".year-select", $container).dxSelectBox("option", "value", v);
        }
    }
});

class DxExtClass {
    define(opt) {
        DxExtInstance.define(opt);
    }
}

export let DxExt = new DxExtClass();